package de.h_da.fbi.cg.pointcloud.emst;

import java.util.ArrayList;
import java.util.Random;

import junit.framework.Assert;

import org.junit.Before;
import org.junit.Test;

import de.h_da.fbi.cg.pointcloud.adt.Graph;
import de.h_da.fbi.cg.pointcloud.adt.Vertex;
import de.h_da.fbi.cg.pointcloud.util.GraphUtil;

/**
 * @author Nicolas Gramlich
 * @since 20:28:05 - 12.11.2010
 */
public abstract class BaseEuclideanMinimumSpanningTreeAlgorithmBenchmark {
	// ===========================================================
	// Constants
	// ===========================================================

	private static final Random RANDOM = new Random(1234567890);

	private static final int VERTEX_COUNT = 100000;

	// ===========================================================
	// Fields
	// ===========================================================

	protected IEuclideanMinimumSpanningTreeAlgorithm mEuclideanMinimumSpanningTreeAlgorithm;
	private final ArrayList<Vertex> mVertices;

	// ===========================================================
	// Constructors
	// ===========================================================

	public BaseEuclideanMinimumSpanningTreeAlgorithmBenchmark() {
		this.mVertices = new ArrayList<Vertex>();
		for(int i = 0; i < BaseEuclideanMinimumSpanningTreeAlgorithmBenchmark.VERTEX_COUNT; i++) {
			this.mVertices.add(new Vertex(BaseEuclideanMinimumSpanningTreeAlgorithmBenchmark.RANDOM.nextFloat(), BaseEuclideanMinimumSpanningTreeAlgorithmBenchmark.RANDOM.nextFloat(), BaseEuclideanMinimumSpanningTreeAlgorithmBenchmark.RANDOM.nextFloat()));
		}
	}

	@Before
	public abstract void setUp() throws Exception;

	// ===========================================================
	// Getter & Setter
	// ===========================================================

	// ===========================================================
	// Methods for/from SuperClass/Interfaces
	// ===========================================================

	@Test
	public void testComputeEuclideanMinimumSpanningTreeSimpleRandom() throws Exception {
		long start;
		long end;
		for(int i = 5; i <= 50; i++) {
			start = System.currentTimeMillis();
			final Graph euclideanMinimumSpanningTree = this.benchmark(i).get(0);
			end = System.currentTimeMillis();
			
			Assert.assertEquals(this.mVertices.size() - 1, euclideanMinimumSpanningTree.getEdges().size());

			System.out.println(this.mVertices.size() + "\t" + i + "\t" + (end - start) / 1000f + "\t" + euclideanMinimumSpanningTree.getEdges().getTotalLenght());
		}
	}

	private ArrayList<Graph> benchmark(final int pNearestNeighborCount) {
		final ArrayList<Graph> components = GraphUtil.createComponentsWithNearestNeighborEdges(this.mVertices, pNearestNeighborCount);

		return this.mEuclideanMinimumSpanningTreeAlgorithm.computeEuclideanMinimumSpanningTree(components);
	}

	// ===========================================================
	// Methods
	// ===========================================================

	// ===========================================================
	// Inner and Anonymous Classes
	// ===========================================================
}
